package mac10.util;

import java.util.ArrayList;

import mac10.models.Cell;
import mac10.models.Point;
import mac10.models.WorldModel;

/*
 * this class is only used in this class itself...
 */

@Deprecated
public class AStarHeapStatic {

	private static WorldModel world;
	private static Node start, goal;
	private static ArrayList<Node> closedlist;
	private static OpenHeap openlist;
	private static boolean avoidFences, avoidCows, avoidAgents;
	
	public static void initializeAStarHeapStatic(WorldModel world)
	{
		AStarHeapStatic.world = world;
	}

	/**
	 * Calculates the path from start to goal
	 * If path was found, the path can be reconstructed recursively with the predecessor of the goal-node
	 * @return goal-node or null if no path was found
	 */
	public static synchronized Node AStar(WorldModel world, Point start, Point goal)
	{
		AStarHeapStatic.world = world;
		openlist = new OpenHeap();
		closedlist = new ArrayList<Node>();
		int fstart = 0 + start.maxNorm(goal);
		AStarHeapStatic.start = new Node(start, 0, fstart);
		AStarHeapStatic.goal = new Node(goal, Integer.MAX_VALUE, Integer.MAX_VALUE);
		AStarHeapStatic.openlist = new OpenHeap();
		AStarHeapStatic.closedlist = new ArrayList<Node>();
		openlist.add(AStarHeapStatic.start);
		
		while(!openlist.isEmpty())
		{
			Node curr = openlist.poll();
//			System.out.println(curr);
			if (curr.equals(goal)) return curr;
			expandNode(curr);
			
			closedlist.add(curr);
		}
		return null;
	}
	
	private static void expandNode(Node curr)
	{
		ArrayList<Cell> cells = AStarHeapStatic.world.getNeighbours(curr.getX(), curr.getY());
        for (Cell cell : cells) {
        	
        	// these cells are never accessible
			if (cell.isObstacle() || cell.isSwitch())
				continue;
			if(avoidFences && cell.isFence() && !cell.isOpen())
				continue;
			if(avoidCows && cell.isCow())
				continue;
			if(avoidAgents && (cell.isAllyAgent() || cell.isEnemyAgent()))
				continue;
			
			int fsucc = curr.getG() + 1 + goal.maxNorm(cell);
			Node successor = new Node(cell, curr.getG() + 1, fsucc, curr);
//			System.out.println("\t"+successor+" f: "+fsucc);
			if (closedlist.contains(successor))
				continue;
			
			if (openlist.contains(successor))
			{
				openlist.updateNode(successor);
			}
			else
			{
				openlist.add(successor);
			}
		}
	}

	/**
	 * @return the avoidFences
	 */
	public static boolean isAvoidFences() {
		return avoidFences;
	}

	/**
	 * @param avoidFences the avoidFences to set
	 */
	public static void setAvoidFences(boolean avoidFences) {
		AStarHeapStatic.avoidFences = avoidFences;
	}

	/**
	 * @return the avoidCows
	 */
	public static boolean isAvoidCows() {
		return avoidCows;
	}

	/**
	 * @param avoidCows the avoidCows to set
	 */
	public static void setAvoidCows(boolean avoidCows) {
		AStarHeapStatic.avoidCows = avoidCows;
	}

	/**
	 * @return the avoidAgents
	 */
	public static boolean isAvoidAgents() {
		return avoidAgents;
	}

	/**
	 * @param avoidAgents the avoidAgents to set
	 */
	public static void setAvoidAgents(boolean avoidAgents) {
		AStarHeapStatic.avoidAgents = avoidAgents;
	}
}
